const fetch = require('./lib/fetch');
const header = require('./lib/headers');

function orderJSONData(option) {
  let jsonData = option.json;
  if (jsonData != null) {
    let headers = option.headers;
    if (headers) {
      if (headers instanceof header) {
        headers.set('Content-Type', 'application/json;charset=UTF-8');
      }
      else if (Array.isArray(headers)) {
        headers.push(['Content-Type', 'application/json;charset=UTF-8']);
      }
      else {
        headers['Content-Type'] = 'application/json;charset=UTF-8';
      }
    }
    else {
      headers = { 'Content-Type': 'application/json;charset=UTF-8' };
    }
    option.headers = headers;
    if (typeof jsonData === 'string') {
      option.body = jsonData;
    }
    else {
      option.body = JSON.stringify(jsonData);
    }
    delete option.json;
  }
}
class HttpStatusError extends Error {
  constructor(status, msg) {
    super(msg);
    this.status = status;
  }
  toString() {
    return `${this.status} & ${this.message}`;
  }
}
function checkStatus(res, accept) {
  if (res.ok) { // res.status >= 200 && res.status < 300
    accept = accept || res.headers.get('Content-Type') || 'text';
    if (/json/.test(accept)) {
      return res.json();
    }
    else if (/form-data/.test(accept)) {
      return res.formData();
    }
    else if (/text/.test(accept)) {
      return res.text();
    }
    else {
      return res[accept]();
    }
  }
  else {
    throw new HttpStatusError(res.status, res.statusText);
  }
}
function phax(url, option) {
  let accept; // 默认返回 JSON
  if (url != null) {
    if (typeof url === 'string') { // 第一个参数为 url
      if (option == null) { // 只传递了 url，则直接执行 fetch get 请求
        return fetch(url).then(res => checkStatus(res, accept));
      }
      else { // 传递了两个参数
        if (typeof option === 'object') { // option
          accept = option.accept;
          delete option.accept;
          orderJSONData(option); // 整理 json 参数
          return fetch(url, option).then(res => checkStatus(res, accept));
        }
        else {
          accept = String(option);
          return fetch(url).then(res => checkStatus(res, accept));
        }
      }
    }
    else { // 第一个参数直接传递的配置形式
      let uri = url.url;
      if (uri != null) {
        accept = url.accept;
        delete url.accept;
        orderJSONData(url); // 整理 json 参数
        delete url.url;
        return fetch(uri, url).then(res => checkStatus(res, accept));
      }
      else {
        Promise.reject(new Error('fetch url is required'));
      }
    }
  }
  else {
    Promise.reject(new Error('fetch url is required'));
  }
}

module.exports = phax;
